/*
 * Copyright 2023, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "accelerant.h"

#include <string.h>

/*!	Set the shape of the hardware cursor. The cursor is attached
    to the frame buffer memory area, and will be displayed if the
    hardware cursor is enabled.
*/
status_t
ls7a2000_set_cursor_shape(uint16 width, uint16 height, uint16 hotX,
                          uint16 hotY, uint8 *andMask, uint8 *xorMask)
{
    TRACE(("ls7a2000_set_cursor_shape(%d, %d, %d, %d)\n",
           width, height, hotX, hotY));

    // 检查参数有效性
    if (width > 64 || height > 64)
        return B_BAD_VALUE;

    // 保存光标热点
    gInfo->shared_info->cursor_hot_x = hotX;
    gInfo->shared_info->cursor_hot_y = hotY;

    // 清空光标缓冲区
    memset(gInfo->shared_info->cursor_memory, 0, 64 * 64 * 4);

    // 将光标数据转换为ARGB32格式并复制到光标缓冲区
    uint32 *cursor = (uint32 *)gInfo->shared_info->cursor_memory;
    for (uint16 y = 0; y < height; y++)
    {
        for (uint16 x = 0; x < width; x++)
        {
            uint8 andBit = andMask[y * ((width + 7) / 8) + (x / 8)] & (1 << (7 - (x % 8)));
            uint8 xorBit = xorMask[y * ((width + 7) / 8) + (x / 8)] & (1 << (7 - (x % 8)));

            uint32 color = 0;
            if (andBit && !xorBit) // 透明
                color = 0x00000000;
            else if (!andBit && !xorBit) // 黑色
                color = 0xff000000;
            else if (andBit && xorBit) // 白色
                color = 0xffffffff;
            else // 反色（不支持，使用白色）
                color = 0xffffffff;

            cursor[y * 64 + x] = color;
        }
    }

    // 设置光标格式为ARGB32
    gInfo->shared_info->cursor_format = B_RGBA32;

    // 启用硬件光标
    uint32 cursorControl = read32(LS7A_CURSOR_CONTROL);
    cursorControl |= LS7A_CURSOR_ENABLE;
    write32(LS7A_CURSOR_CONTROL, cursorControl);

    return B_OK;
}

/*!	Move the hardware cursor to the specified position on the screen. */
void ls7a2000_move_cursor(uint16 x, uint16 y)
{
    TRACE(("ls7a2000_move_cursor(%d, %d)\n", x, y));

    // 设置光标位置
    write32(LS7A_CURSOR_POS, ((uint32)y << 16) | x);
}

/*!	Show/hide the hardware cursor. */
void ls7a2000_show_cursor(bool isVisible)
{
    TRACE(("ls7a2000_show_cursor(%s)\n", isVisible ? "true" : "false"));

    uint32 cursorControl = read32(LS7A_CURSOR_CONTROL);

    if (isVisible)
        cursorControl |= LS7A_CURSOR_ENABLE;
    else
        cursorControl &= ~LS7A_CURSOR_ENABLE;

    write32(LS7A_CURSOR_CONTROL, cursorControl);
}